package game.dungeon;


import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.nio.channels.IllegalSelectorException;

import game.border.Border;
import game.border.Wall;
import game.square.Direction;
import game.square.Square;
import game.square.SquareInterface;

import org.junit.Before;
import org.junit.Test;

public class CompositeTest {

	@Before
	public void setUp() throws Exception {
		composite = new Composite<SquareInterface>(500,500,500);
	}
	
	private Composite<SquareInterface> composite;
	
	@Test
	public final void shaftOverlapWithShaft() {
		Shaft<SquareInterface> shaftOne = new Shaft<SquareInterface>(0,0,-1,20);
		Shaft<SquareInterface> shaftTwo = new Shaft<SquareInterface>(0,0,-1,20);
		Shaft<SquareInterface> shaftThree = new Shaft<SquareInterface>(1,0,-1,20);
		assertFalse(composite.shaftOverlapWithShaft(shaftOne, new Coordinates(1,0,0), shaftTwo, new Coordinates(1,0,21)));
		assertTrue(composite.shaftOverlapWithShaft(shaftOne, new Coordinates(1,0,0), shaftTwo, new Coordinates(1,0,20)));
		assertFalse(composite.shaftOverlapWithShaft(shaftThree, new Coordinates(1,0,0), shaftTwo, new Coordinates(1,0,0)));
	}

	@Test
	public final void levelOverlapWithShaft() {
		Shaft<SquareInterface> shaft = new Shaft<SquareInterface>(0,0,-1,20);
		Level<SquareInterface> level = new Level<SquareInterface>(10,10,5);
		assertTrue(composite.levelOverlapWithShaft(level, new Coordinates(1,0,0), shaft, new Coordinates(1,0,0)));
		assertFalse(composite.levelOverlapWithShaft(level, new Coordinates(0,0,16), shaft, new Coordinates()));
	}
	
	@Test
	public final void compositeOverlapWithShaft() {
		Shaft<SquareInterface> shaft = new Shaft<SquareInterface>(0,0,-1,20);
		assertTrue(composite.compositeOverlapWithShaft(composite, new Coordinates(0,0,0), shaft, new Coordinates(1,1,1)));
		assertFalse(composite.compositeOverlapWithShaft(composite, new Coordinates(0,0,0), shaft, new Coordinates(0,0,501)));
	}
	
	@Test
	public final void levelOverlapWithLevel() {
		Level<SquareInterface> levelOne = new Level<SquareInterface>(10,10,0);
		Level<SquareInterface> levelTwo = new Level<SquareInterface>(10,10,0);
		assertTrue(composite.levelOverlapWithlevel(levelOne, new Coordinates(0,0,0), levelTwo, new Coordinates(0,0,0)));
		assertFalse(composite.levelOverlapWithlevel(levelOne, new Coordinates(0,0,1), levelTwo, new Coordinates(0,0,0)));
		assertTrue(composite.levelOverlapWithlevel(levelOne, new Coordinates(1,0,0), levelTwo, new Coordinates(0,5,0)));
	}
	
	@Test
	public final void compositeOverlapWithLevel() {
		Level<SquareInterface> level = new Level<SquareInterface>(10,10,1);
		assertTrue(composite.compositeOverlapWithLevel(composite, new Coordinates(0,0,0), level, new Coordinates(0,0,10)));
		assertFalse(composite.compositeOverlapWithLevel(composite, new Coordinates(0,0,0), level, new Coordinates(0,0,500)));
	}
	
	@Test
	public final void compositeOverlapWithComposite() {
		assertTrue(composite.compositeOverlapWithComposite(composite, new Coordinates(), composite, new Coordinates()));
		assertTrue(composite.compositeOverlapWithComposite(composite, new Coordinates(499,500,8), composite, new Coordinates(0,0,0)));
		assertFalse(composite.compositeOverlapWithComposite(composite, new Coordinates(0,0,0), composite, new Coordinates(501,501,501)));
	}
	
	@Test
	public final void testAddDungeon_legalCase() {
		Level<SquareInterface> level = new Level<SquareInterface>(50,50,0);
		Shaft<SquareInterface> shaft = new Shaft<SquareInterface>(0,0,-1,10);
		composite.addSubDungeon(new Coordinates(1,0,0), level);
		composite.addSubDungeon(new Coordinates(52,51,1), shaft);
	}
	
	@Test (expected=IllegalArgumentException.class)
	public final void testAddDungeon_illegalCase() {
		Level<SquareInterface> level1 = new Level<SquareInterface>(50,50,0);
		Level<SquareInterface> level2 = new Level<SquareInterface>(50,50,0);
		composite.addSubDungeon(new Coordinates(1,0,0), level1);
		composite.addSubDungeon(new Coordinates(25,25,0), level2);
	}
	
	@Test
	public final void testGetSquare() {
		Square square = new Square(new Border(Direction.EAST,new Wall()));
		Level<SquareInterface> level = new Level<SquareInterface>(10,10,10);
		level.addSquare(square, new Coordinates(10,9,10));
		composite.addSubDungeon(new Coordinates(0,1,0), level);
		if(composite.getCoordinates(square) == null)
			throw new IllegalStateException();
		if(composite.getSquare(composite.getCoordinates(square)) != square)
			throw new IllegalSelectorException();
	}
	
	@Test
	public final void testGetSubDungeon() {
		Level<SquareInterface> level = new Level<SquareInterface>(10,10,10);
		composite.addSubDungeon(new Coordinates(0,1,0), level);
		System.out.println(composite.getRelativeCoordinates(level).toString());
		if(!composite.getRelativeCoordinates(level).equals(new Coordinates(0,1,0)))
			throw new IllegalStateException();
	}
}
